﻿using BCCommon;
using BCCommon.Enums;
using BCData.OA.WorkflowTemplate.WorkflowTemplateStepFormConfig;
using BCDto.OA.WorkflowTemplate.WorkflowTemplateStepFormConfig;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateStepFormConfig;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BCData.OA.WorkflowTemplate.WorkflowTemplateStepFormCategory;
using BCData.OA.WorkflowTemplate.WorkflowTemplateStepFormDatabaseConfig;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateStepFormDatabaseConfig;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateStepFormItem;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateFormCustomDatabase;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateFormCustomDatabaseTable;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateFormCustomDatabaseTableColumn;
using BCCommon.OAEnums;
using BCData.OA.WorkflowTemplate.WorkflowTemplateFormCustomDatabase;
using BCData.OA.WorkflowTemplate.WorkflowTemplateFormCustomDatabaseTable;
using BCData.OA.WorkflowTemplate.WorkflowTemplateFormCustomDatabaseTableColumn;
using BCData.OA.WorkflowTemplate.WorkflowTemplateStepFormItem;
using BCDto.OA.WorkflowTemplate.WorkflowTemplateStepFormCategory;
using BCEntity.OA.WorkflowTemplate.WorkflowTemplateStepFormCategory;
using BCDto.Sim.Admin.Admin;

namespace BCService.OA.WorkflowTemplate.WorkflowTemplateStepFormConfig
{
	public class WorkflowTemplateStepFormConfigService : IWorkflowTemplateStepFormConfigService
	{
		private readonly IDatabaseContext databaseContext;
		private readonly IRedisService redisService;
		private readonly IWorkflowTemplateStepFormConfigData workflowTemplateStepFormConfigData;
		private readonly IWorkflowTemplateStepFormCategoryData workflowTemplateStepFormCategoryData;
		private readonly IWorkflowTemplateStepFormItemData workflowTemplateStepFormItemData;
		private readonly IWorkflowTemplateStepFormDatabaseConfigData workflowTemplateStepFormDatabaseConfigData;
		private readonly IWorkflowTemplateFormCustomDatabaseData workflowTemplateFormCustomDatabaseData;
		private readonly IWorkflowTemplateFormCustomDatabaseTableData workflowTemplateFormCustomDatabaseTableData;
		private readonly IWorkflowTemplateFormCustomDatabaseTableColumnData workflowTemplateFormCustomDatabaseTableColumnData;
		private readonly string key = string.Format("{0}", EntityNameConst.WorkflowTemplateStepFormConfigEntity);

		public WorkflowTemplateStepFormConfigService(IDatabaseContext databaseContext,
			IRedisService redisService,
			IWorkflowTemplateStepFormConfigData workflowTemplateStepFormConfigData,
			IWorkflowTemplateStepFormCategoryData workflowTemplateStepFormCategoryData,
			IWorkflowTemplateStepFormItemData workflowTemplateStepFormItemData,
			IWorkflowTemplateStepFormDatabaseConfigData workflowTemplateStepFormDatabaseConfigData,
			IWorkflowTemplateFormCustomDatabaseData workflowTemplateFormCustomDatabaseData,
			IWorkflowTemplateFormCustomDatabaseTableData workflowTemplateFormCustomDatabaseTableData,
			IWorkflowTemplateFormCustomDatabaseTableColumnData workflowTemplateFormCustomDatabaseTableColumnData)
		{
			this.databaseContext = databaseContext;
			this.redisService = redisService;
			this.workflowTemplateStepFormConfigData = workflowTemplateStepFormConfigData;
			this.workflowTemplateStepFormCategoryData = workflowTemplateStepFormCategoryData;
			this.workflowTemplateStepFormItemData = workflowTemplateStepFormItemData;
			this.workflowTemplateStepFormDatabaseConfigData = workflowTemplateStepFormDatabaseConfigData;
			this.workflowTemplateFormCustomDatabaseData = workflowTemplateFormCustomDatabaseData;
			this.workflowTemplateFormCustomDatabaseTableData = workflowTemplateFormCustomDatabaseTableData;
			this.workflowTemplateFormCustomDatabaseTableColumnData = workflowTemplateFormCustomDatabaseTableColumnData;
		}

		#region 检查工作流模板步骤表单配置是否存在
		public bool Exists(long workflowTemplateStepFormConfigId)
		{
			return this.workflowTemplateStepFormConfigData.Exists(workflowTemplateStepFormConfigId).GetAwaiter().GetResult();
		}
		#endregion

		#region 添加工作流模板步骤表单配置
		public WorkflowTemplateStepFormConfigDto Add(WorkflowTemplateStepFormConfigRequestDto requestDto,AdminDto adminDto)
		{
            if (!this.workflowTemplateStepFormCategoryData.Exists(requestDto.FormCategoryCode).GetAwaiter().GetResult())
            {
				throw new ArgumentException("此分类不存在!");
            }
			var formCategoryEntity = this.workflowTemplateStepFormCategoryData.GetEntity(requestDto.FormCategoryCode).GetAwaiter().GetResult();
			var entity = requestDto.As<WorkflowTemplateStepFormConfigEntity>();
			entity.FormCategoryName = formCategoryEntity.FormCategoryName;
			entity.CreateAdminName = adminDto.FullName;
			entity.CreateAdminId = adminDto.AdminId;
			if (entity.IsSpecificForm)
			{
				var result = this.workflowTemplateStepFormConfigData.Add(entity).GetAwaiter().GetResult().As<WorkflowTemplateStepFormConfigDto>();
				if (result == null) {
					throw new ArgumentException("添加工作流表模板表单配置失败!");
				}
				this.redisService.DeleteMultipleKey(key, false);
				return result;
			}
			else
			{
				var itemEntities = requestDto.FormItemTemplate.TransformTo<WorkflowTemplateStepFormItemEntity>(onAfter: (source, dest) =>
				{
					dest.FormConfigCode = entity.FormConfigCode;
					dest.FormConfigTitle = entity.FormConfigTitle;
					dest.CreateAdminName = adminDto.FullName;
					dest.CreateAdminId = adminDto.AdminId;
				}).ToList();
				var databaseConfigEntities = requestDto.DatabaseConfig.TransformTo<WorkflowTemplateStepFormDatabaseConfigEntity>(onAfter: (source, dest) =>
				{
					dest.DataSourceType = source.DataSourceType;
					dest.DatabaseComment = source.DatabaseComment;
					dest.DatabaseName = source.DatabaseName;
					dest.FormCategoryCode = formCategoryEntity.FormCategoryCode;
					dest.FormCategoryName = formCategoryEntity.FormCategoryName;
					dest.FormConfigCode = entity.FormConfigCode;
					dest.FormConfigTitle = entity.FormConfigTitle;
					dest.CreateAdminName = adminDto.FullName;
					dest.CreateAdminId = adminDto.AdminId;
				}).ToList();

				List<WorkflowTemplateFormCustomDatabaseEntity> customDatabaseEntities = new List<WorkflowTemplateFormCustomDatabaseEntity>();
				List<WorkflowTemplateFormCustomDatabaseTableEntity> customDatabaseTableEntities = new List<WorkflowTemplateFormCustomDatabaseTableEntity>();
				List<WorkflowTemplateFormCustomDatabaseTableColumnEntity> customDatabaseTableColmunEntities = new List<WorkflowTemplateFormCustomDatabaseTableColumnEntity>();

				foreach (var item in requestDto.DatabaseConfig)
				{
					if (item.DataSourceType == OADataSourceType.CustomData)
					{

						WorkflowTemplateFormCustomDatabaseEntity databaseEntity = new WorkflowTemplateFormCustomDatabaseEntity
						{
							FormConfigTitle = entity.FormConfigTitle,
							FormConfigCode = entity.FormConfigCode,
							DatabaseComment = item.DatabaseComment,
							DatabaseName = item.DatabaseName
						};
						customDatabaseEntities.Add(databaseEntity);

						foreach (var table in item.Tables)
						{
							WorkflowTemplateFormCustomDatabaseTableEntity tableEntity = new WorkflowTemplateFormCustomDatabaseTableEntity
							{
								FormConfigTitle = entity.FormConfigTitle,
								FormConfigCode = entity.FormConfigCode,
								DatabaseComment = item.DatabaseComment,
								DatabaseName = item.DatabaseName,
								TableComment = table.TableComment,
								TableName = table.TableName
							};
							customDatabaseTableEntities.Add(tableEntity);

							foreach (var column in table.Columns)
							{
								WorkflowTemplateFormCustomDatabaseTableColumnEntity columnEntity = new WorkflowTemplateFormCustomDatabaseTableColumnEntity
								{
									FormConfigTitle = entity.FormConfigTitle,
									FormConfigCode = entity.FormConfigCode,
									DatabaseComment = item.DatabaseComment,
									DatabaseName = item.DatabaseName,
									TableComment = table.TableComment,
									TableName = table.TableName,
									ColumnComment = column.ColumnComment,
									ColumnName = column.ColumnName,
									ColumnType = column.ColumnType,
									Value = column.Value
								};
								customDatabaseTableColmunEntities.Add(columnEntity);
							}
						}
					}
				}

				databaseContext.BeginTransaction();
				var result = this.workflowTemplateStepFormConfigData.Add(entity).GetAwaiter().GetResult().As<WorkflowTemplateStepFormConfigDto>();
				if (!this.workflowTemplateStepFormItemData.Add(itemEntities).GetAwaiter().GetResult())
				{
					throw new ArgumentException("添加工作流模板表单数据库配置信息失败!");
				}
				if (!this.workflowTemplateStepFormDatabaseConfigData.Add(databaseConfigEntities).GetAwaiter().GetResult())
				{
					throw new ArgumentException("添加工作流模板表单数据库配置信息失败!");
				}

				if (customDatabaseEntities.Any())
				{
					if (!this.workflowTemplateFormCustomDatabaseData.Add(customDatabaseEntities).GetAwaiter().GetResult())
					{
						throw new ArgumentException("添加工作流模板表单自定义数据库信息失败!");
					}
					if (!this.workflowTemplateFormCustomDatabaseTableData.Add(customDatabaseTableEntities).GetAwaiter().GetResult())
					{
						throw new ArgumentException("添加工作流模板表单自定义数据库信息失败!");
					}
					if (!this.workflowTemplateFormCustomDatabaseTableColumnData.Add(customDatabaseTableColmunEntities).GetAwaiter().GetResult())
					{
						throw new ArgumentException("添加工作流模板表单自定义数据库信息失败!");
					}
				}
				databaseContext.Commit();
				this.redisService.DeleteMultipleKey(key, false);
				return result;
			}
		}
		#endregion

		#region 修改工作流模板步骤表单配置
		public WorkflowTemplateStepFormConfigDto Update(WorkflowTemplateStepFormConfigPutDto putDto,AdminDto adminDto)
		{
			if (!this.Exists(putDto.WorkflowTemplateStepFormConfigId))
			{
				throw new ArgumentException("此记录不存在!");
			}
			if (!this.workflowTemplateStepFormCategoryData.Exists(putDto.FormCategoryCode).GetAwaiter().GetResult())
			{
				throw new ArgumentException("此分类不存在!");
			}
			var formCategoryEntity = this.workflowTemplateStepFormCategoryData.GetEntity(putDto.FormCategoryCode).GetAwaiter().GetResult();
			var entity = putDto.As<WorkflowTemplateStepFormConfigEntity>();
			entity.FormCategoryName = formCategoryEntity.FormCategoryName;
			entity.EditAdminName = adminDto.FullName;
			entity.EditAdminId = adminDto.AdminId;
			if (entity.IsSpecificForm)
			{
				var result = this.workflowTemplateStepFormConfigData.Update(entity).GetAwaiter().GetResult().As<WorkflowTemplateStepFormConfigDto>();
				if (result == null)
				{
					throw new ArgumentException("修改工作流表模板表单配置失败!");
				}
				this.redisService.DeleteMultipleKey(key, false);
				return result;
			}
			else
			{
				var itemEntities = putDto.FormItemTemplate.TransformTo<WorkflowTemplateStepFormItemEntity>(onAfter: (source, dest) =>
			{
				dest.FormConfigCode = entity.FormConfigCode;
				dest.FormConfigTitle = entity.FormConfigTitle;
				dest.CreateAdminName = adminDto.FullName;
				dest.CreateAdminId = adminDto.AdminId;
			}).ToList();
				var databaseConfigEntities = putDto.DatabaseConfig.TransformTo<WorkflowTemplateStepFormDatabaseConfigEntity>(onAfter: (source, dest) =>
				{
					dest.DataSourceType = source.DataSourceType;
					dest.DatabaseComment = source.DatabaseComment;
					dest.DatabaseName = source.DatabaseName;
					dest.FormCategoryCode = formCategoryEntity.FormCategoryCode;
					dest.FormCategoryName = formCategoryEntity.FormCategoryName;
					dest.FormConfigCode = entity.FormConfigCode;
					dest.FormConfigTitle = entity.FormConfigTitle;
					dest.CreateAdminName = adminDto.FullName;
					dest.CreateAdminId = adminDto.AdminId;
				}).ToList();

				List<WorkflowTemplateFormCustomDatabaseEntity> customDatabaseEntities = new List<WorkflowTemplateFormCustomDatabaseEntity>();
				List<WorkflowTemplateFormCustomDatabaseTableEntity> customDatabaseTableEntities = new List<WorkflowTemplateFormCustomDatabaseTableEntity>();
				List<WorkflowTemplateFormCustomDatabaseTableColumnEntity> customDatabaseTableColmunEntities = new List<WorkflowTemplateFormCustomDatabaseTableColumnEntity>();

				foreach (var item in putDto.DatabaseConfig)
				{
					if (item.DataSourceType == OADataSourceType.CustomData)
					{
						WorkflowTemplateFormCustomDatabaseEntity databaseEntity = new WorkflowTemplateFormCustomDatabaseEntity
						{
							FormConfigTitle = entity.FormConfigTitle,
							FormConfigCode = entity.FormConfigCode,
							DatabaseComment = item.DatabaseComment,
							DatabaseName = item.DatabaseName
						};
						customDatabaseEntities.Add(databaseEntity);

						foreach (var table in item.Tables)
						{
							WorkflowTemplateFormCustomDatabaseTableEntity tableEntity = new WorkflowTemplateFormCustomDatabaseTableEntity
							{
								FormConfigTitle = entity.FormConfigTitle,
								FormConfigCode = entity.FormConfigCode,
								DatabaseComment = item.DatabaseComment,
								DatabaseName = item.DatabaseName,
								TableComment = table.TableComment,
								TableName = table.TableName
							};
							customDatabaseTableEntities.Add(tableEntity);

							foreach (var column in table.Columns)
							{
								WorkflowTemplateFormCustomDatabaseTableColumnEntity columnEntity = new WorkflowTemplateFormCustomDatabaseTableColumnEntity
								{
									FormConfigTitle = entity.FormConfigTitle,
									FormConfigCode = entity.FormConfigCode,
									DatabaseComment = item.DatabaseComment,
									DatabaseName = item.DatabaseName,
									TableComment = table.TableComment,
									TableName = table.TableName,
									ColumnComment = column.ColumnComment,
									ColumnName = column.ColumnName,
									ColumnType = column.ColumnType,
									Value = column.Value
								};
								customDatabaseTableColmunEntities.Add(columnEntity);
							}
						}
					}
				}

				databaseContext.BeginTransaction();
				var result = this.workflowTemplateStepFormConfigData.Update(entity).GetAwaiter().GetResult().As<WorkflowTemplateStepFormConfigDto>();
				this.workflowTemplateStepFormItemData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
				if (!this.workflowTemplateStepFormItemData.Add(itemEntities).GetAwaiter().GetResult())
				{
					throw new ArgumentException("修改工作流模板表单数据库配置信息失败!");
				}
				this.workflowTemplateStepFormDatabaseConfigData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
				if (!this.workflowTemplateStepFormDatabaseConfigData.Add(databaseConfigEntities).GetAwaiter().GetResult())
				{
					throw new ArgumentException("修改工作流模板表单数据库配置信息失败!");
				}

				if (customDatabaseEntities.Any())
				{
					this.workflowTemplateFormCustomDatabaseTableColumnData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
					this.workflowTemplateFormCustomDatabaseTableData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
					this.workflowTemplateFormCustomDatabaseData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();

					if (!this.workflowTemplateFormCustomDatabaseData.Add(customDatabaseEntities).GetAwaiter().GetResult())
					{
						throw new ArgumentException("修改工作流模板表单自定义数据库信息失败!");
					}

					if (!this.workflowTemplateFormCustomDatabaseTableData.Add(customDatabaseTableEntities).GetAwaiter().GetResult())
					{
						throw new ArgumentException("修改工作流模板表单自定义数据库信息失败!");
					}

					if (!this.workflowTemplateFormCustomDatabaseTableColumnData.Add(customDatabaseTableColmunEntities).GetAwaiter().GetResult())
					{
						throw new ArgumentException("修改工作流模板表单自定义数据库信息失败!");
					}
				}
				databaseContext.Commit();
				this.redisService.DeleteMultipleKey(key, false);
				return result;
			}
		}
		#endregion

		#region 删除工作流模板步骤表单配置
		public bool Delete(long workflowTemplateStepFormConfigId)
		{
			if (!this.Exists(workflowTemplateStepFormConfigId))
			{
				throw new ArgumentException("此记录不存在!");
			}
			var entity = this.workflowTemplateStepFormConfigData.GetEntity(workflowTemplateStepFormConfigId).GetAwaiter().GetResult();
			this.workflowTemplateStepFormItemData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
			this.workflowTemplateStepFormDatabaseConfigData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
			this.workflowTemplateFormCustomDatabaseTableColumnData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
			this.workflowTemplateFormCustomDatabaseTableData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
			this.workflowTemplateFormCustomDatabaseData.Delete(entity.FormConfigCode).GetAwaiter().GetResult();
			var result = this.workflowTemplateStepFormConfigData.Delete(workflowTemplateStepFormConfigId).GetAwaiter().GetResult();
			this.redisService.DeleteMultipleKey(key, false);
			return result;
		}
		#endregion

		#region 获取工作流模板步骤表单配置
		public WorkflowTemplateStepFormConfigDto Get(long workflowTemplateStepFormConfigId)
		{
			string cacheKey = this.redisService.GetKey(key, workflowTemplateStepFormConfigId);
			var result = this.redisService.TryGet(cacheKey, () =>
			{
				var data = this.workflowTemplateStepFormConfigData.GetEntity(workflowTemplateStepFormConfigId).GetAwaiter().GetResult();
				return data;
			}, TimeSpan.FromDays(1));
			return result.As<WorkflowTemplateStepFormConfigDto>();
		}
		#endregion

		#region 获取工作流模板步骤表单配置列表
		public IEnumerable<WorkflowTemplateStepFormConfigDto> GetList(string formCategoryCode)
		{
			string cacheKey = this.redisService.GetKey(key, formCategoryCode);
			var result = this.redisService.TryGet(cacheKey, () =>
			{
				return this.workflowTemplateStepFormConfigData.GetList(formCategoryCode).GetAwaiter().GetResult();
			}, TimeSpan.FromDays(1));
			return result.As<IEnumerable<WorkflowTemplateStepFormConfigDto>>();
		}
		#endregion

		#region 获取工作流模板步骤表单配置分页
		public PageableList<WorkflowTemplateStepFormConfigDto> Query(string formCategoryCode, string formConfigTitle,DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
		{
			string cacheKey = this.redisService.GetKey(key, formCategoryCode, formConfigTitle,start, end, sortName, ascending, pageIndex, pageSize);
			var result = this.redisService.TryGet(cacheKey, () =>
			{
				var data = this.workflowTemplateStepFormConfigData.Query(formCategoryCode, formConfigTitle, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
				return new PageableList<WorkflowTemplateStepFormConfigDto>
				{
					Count = data.Item2,
					Items = data.Item1.As<IEnumerable<WorkflowTemplateStepFormConfigDto>>(),
					PageIndex = pageIndex,
					PageSize = pageSize,
					ServerTime = DateTime.Now
				};
			}, TimeSpan.FromMinutes(30));

			return result;
		}
		#endregion

		#region 获取自定义表单属性列表
		public List<object> TemplateTree()
		{
			
			string cacheKey = "CustomFormTemplateTree";
			var result = this.redisService.TryGet(cacheKey, () =>
			{
				IEnumerable<WorkflowTemplateStepFormCategoryEntity> categoryDtos = this.workflowTemplateStepFormCategoryData.GetList().GetAwaiter().GetResult();
				List<object> resultTree = GetTree(categoryDtos);
				return resultTree;
			}, TimeSpan.FromDays(1));
			return result;
		}
		#endregion
		#region 私有方法
		/// <summary>
		/// 获取自定义表单属性列表
		/// </summary>
		/// <param name="categoryDtos">分类列表</param>
		/// <returns></returns>
		private List<object> GetTree(IEnumerable<WorkflowTemplateStepFormCategoryEntity> categoryDtos)
		{
			List<object> resultTree = new List<object>();
			foreach (var category in categoryDtos)
			{
				IEnumerable<WorkflowTemplateStepFormConfigDto> list = this.GetList(category.FormCategoryCode);
				if (!list.Any())
				{
					object companyObj = new
					{
						Title = category.FormCategoryName,
						Key = string.Format("{0}-{1}", "Category", category.WorkflowTemplateStepFormCategoryId),
						Selectable = false,
						Origin = category,
						DisableCheckbox = true,
						isLeaf = true
					};
					resultTree.Add(companyObj);
				}
				else
				{
					
					List<object> children = new List<object>();
					foreach (var item in list)
					{
						object child = new
						{
							Title = item.FormConfigTitle,
							Key = string.Format("{0}-{1}", "TemplateForm", item.WorkflowTemplateStepFormConfigId),
							Origin = item,
							DisableCheckbox = false,
							Selectable = true,
							isLeaf = true
						};
						children.Add(child);
					}
					object companyObj = new
					{
						Title = category.FormCategoryName,
						Key = string.Format("{0}-{1}", "Category", category.WorkflowTemplateStepFormCategoryId),
						DisableCheckbox = true,
						Origin = category,
						Selectable = true,
						Children = children.ToArray()
					};
					resultTree.Add(companyObj);
				}
			}
			return resultTree;
		}
        #endregion
    }
}